package com.framewiki.gpt.filter;

import com.cdkjframework.builder.ResponseBuilder;
import com.cdkjframework.config.CustomConfig;
import com.cdkjframework.constant.IntegerConsts;
import com.cdkjframework.exceptions.UserRuntimeException;
import com.cdkjframework.util.encrypts.JwtUtils;
import com.cdkjframework.util.encrypts.Md5Utils;
import com.cdkjframework.util.log.LogUtils;
import com.cdkjframework.util.tool.JsonUtils;
import com.cdkjframework.util.tool.StringUtils;
import com.cdkjframework.util.tool.number.ConvertUtils;
import com.framewiki.gpt.config.ChatConfiguration;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @ProjectName: linkeddt-hyqtds
 * @Package: cn.linkeddt.hyqtds.web.sh.filter
 * @ClassName: AuthorityInterceptor
 * @Description: 权限拦截
 * @Author: xiaLin
 * @Date: 2023/4/5 19:01
 * @Version: 1.0
 */

@Component
public class AuthorityInterceptor implements HandlerInterceptor {

  /**
   * 日志
   */
  private LogUtils logUtils = LogUtils.getLogger(AuthorityInterceptor.class);

  /**
   * 配置
   */
  private final ChatConfiguration configuration;

  /**
   * 配置
   */
  private final CustomConfig customConfig;

  /**
   * 受权 token
   */
  private final String tokenUri = "/authorized/token";

  /**
   * 构建函数
   */
  public AuthorityInterceptor(ChatConfiguration configuration, CustomConfig customConfig) {
    this.configuration = configuration;
    this.customConfig = customConfig;
  }

  /**
   * 路由拦截
   *
   * @param request
   * @param response
   * @param object
   * @return
   * @throws Exception
   */
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
    boolean isHandle = true;
    try {
      String token = request.getHeader("token");
      if (StringUtils.isNullAndSpaceOrEmpty(token)) {
        throw new UserRuntimeException("权限认证失败！");
      }
      if (request.getRequestURI().contains(tokenUri)) {
        if (!configuration.getAppKey().equals(token)) {
          throw new UserRuntimeException("权限认证失败！");
        }
      } else {
        Claims claims = JwtUtils.parseJwt(token, customConfig.getJwtKey());
        long expiration = ConvertUtils.convertLong(claims.get("time"));
        if (expiration < System.currentTimeMillis()) {
          throw new UserRuntimeException("token 过期！");
        }
        String user = ConvertUtils.convertString(claims.get("user"));
        String jwtToken = ConvertUtils.convertString(claims.get("token"));

        StringBuilder builder = new StringBuilder();
        builder.append(String.format("user=%s&effective=%s&time=%s&appKey=%s", user, IntegerConsts.THREE, expiration, configuration.getAppKey()));
        String md5Token = Md5Utils.getMd5(builder.toString());

        if (!md5Token.equals(jwtToken)) {
          throw new UserRuntimeException("权限认证失败！");
        }
      }
    } catch (Exception e) {
      returnJson(response, e.getMessage());
      isHandle = false;
    } finally {
      return isHandle;
    }
  }

  /**
   * 输出信息
   *
   * @param response 响应事件
   * @param message  返回消息
   */
  private void returnJson(HttpServletResponse response, String message) {
    PrintWriter writer = null;
    response.setCharacterEncoding("UTF-8");
    response.setContentType("application/json; charset=utf-8");
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    try {
      writer = response.getWriter();
      writer.print(JsonUtils.objectToJsonString(ResponseBuilder.failBuilder(message)));
    } catch (IOException e) {
      logUtils.error("拦截器输出流异常" + e);
    } finally {
      if (writer != null) {
        writer.close();
      }
    }
  }
}